#include "block.h"
#include <assert.h>
#include "def.h"
#include "../lex/lex.h"
#include "../sym_tbl/symbol_table.h"
#include "../log.h"

/**
 * @brief blocks -> blocks block | { blocks }
 * 
 */

/**
 * @brief block 解析
 *  block -> { block } | { block } { block } | ε
 * @param lex 词法分析器
 * @param root_symbol_table 符号表 
 * @return int32_t: 0 分析成功; <0 分析失败
 */
static int32_t block(
    lex_st *lex, 
    root_symbol_table_st *root_symbol_table)
{
    symbol_st *symbol = lex_get_symbol(lex);
    if((symbol == NULL) 
        || (symbol->type != symbol_type_open_brace))
    {
        lex_put_symbol(lex, symbol);
        return 0;
    }

    if(block(lex, root_symbol_table))
    {
        ERR_FUNC_LINE("block failed\n");
        return -1;
    }

    symbol = lex_get_symbol(lex);
    while((symbol != NULL) 
        && (symbol->type == symbol_type_open_brace))
    {
        lex_put_symbol(lex, symbol);
        if(block(lex, root_symbol_table))
        {
            ERR_FUNC_LINE("block failed\n");
            return -1;
        }
        symbol = lex_get_symbol(lex);
    }

    if((symbol == NULL) 
        || (symbol->type != symbol_type_close_brace))
    {
        ERR_FUNC_LINE("symbol isn't symbol_type_close_brace\n");
        return -1;
    }

    return 0;
}

/**
 * @brief block 自测函数
 *
 * @return int 测试失败
 */
int block_test(
    void)
{
    FUNC_BEGIN();

    char *path = "./test_block.txt";
    lex_st *lex = lex_malloc(path);
    assert(lex != NULL);

    root_symbol_table_st * root_symbol_table = root_symbol_table_malloc();
    assert(root_symbol_table != NULL);

    int32_t ret = block(lex, root_symbol_table);
    assert(ret == 0);
    symbol_st *symbol = lex_get_symbol(lex);
    if(symbol != NULL)
    {
        NOTICE("symbol type: %s\n", symbol_type_str(symbol->type));
    }

    assert(symbol == NULL);

    lex_free(lex);
    root_symbol_table_free(root_symbol_table);

    FUNC_FINISH();
    return 0;
}